using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Framework
{
    [Serializable]
    public class WrappedDict <K, T> : IDictionary<K, T>
    {
        [Serializable]
        public struct KVP
        {
            public K Key;
            public T Value;
        }
        
        private Dictionary<K, T> dict = new();
        private bool initialized = false;
        [ReadOnlyRuntime] public WrappedList<KVP> pairs;
        
        public void Init()
        {
            foreach (var pair in pairs)
            {
                dict.Add(pair.Key, pair.Value);
            }
            initialized = true;
        }
        public IEnumerator<KeyValuePair<K, T>> GetEnumerator()
        {
            if (!initialized) Init();
            return dict.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            if (!initialized) Init();
            return GetEnumerator();
        }

        public void Add(KeyValuePair<K, T> item)
        {
            if (!initialized) Init();
            dict.Add(item.Key, item.Value);
        }

        public void Clear()
        {
            if (!initialized) Init();
            dict.Clear();
        }

        public bool Contains(KeyValuePair<K, T> item)
        {
            if (!initialized) Init();
            return dict.Contains(item);
        }

        public void CopyTo(KeyValuePair<K, T>[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public bool Remove(KeyValuePair<K, T> item)
        {
            if (!initialized) Init();
            return dict.Remove(item.Key);
        }
        
        public int Count
        {
            get
            {
                if (!initialized) Init();
                return dict.Count;
            }
        }

        public bool IsReadOnly => false;
        public void Add(K key, T value)
        {
            if (!initialized) Init();
        }

        public bool ContainsKey(K key)
        {
            if (!initialized) Init();
            return dict.ContainsKey(key);
        }

        public bool Remove(K key)
        {
            if (!initialized) Init();
            return dict.Remove(key);
        }

        public bool TryGetValue(K key, out T value)
        {
            if (!initialized) Init();
            return dict.TryGetValue(key, out value);
        }

        public T this[K key]
        {
            get
            {
                if (!initialized) Init();
                return dict[key];
            }
            set
            {
                if (!initialized) Init();
                dict[key] = value;
            }
        }

        public ICollection<K> Keys
        {
            get
            {
                if (!initialized) Init();
                return dict.Keys;
            }
        }

        public ICollection<T> Values
        {
            get
            {
                if (!initialized) Init();
                return dict.Values;
            }
        }
    }
}